package Executor;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicInteger;

public class NickLock {

  private static final Unsafe unsafe;
  private static final long valueOffset;

  static {
    try {
      Class<Unsafe> unsafeClass = Unsafe.class;
      Field theUnsafe = unsafeClass.getDeclaredField("theUnsafe");
      theUnsafe.setAccessible(true);
      unsafe = (Unsafe) theUnsafe.get(null);

      valueOffset = unsafe.objectFieldOffset
        (NickLock.class.getDeclaredField("value"));
    } catch (Exception ex) {
      throw new Error(ex);
    }
  }

  private volatile int value = 0;

  public final int incrementAndGet() {
    return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
  }

  /**
   * 自旋锁
   * 当前值和偏移值比较，将期望值 0 转化为 1
   */
  void lock() {
    for (; ; ) {
      if (unsafe.compareAndSwapInt(this, valueOffset, 0, 1)) {
        return;
      }
      // 线程让步
      Thread.yield();
    }
  }

  void unlock() {
    value = 0;
  }

}
